home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-28 | 9.0 KB | 366 lines | [TEXT/MPS ] |
- /*
- File: VirtualRamOrDiskFile.cp
-
- Copyright: © 1991-1994 by Apple Computer, Inc.
- All rights reserved.
-
- Part of the AOCE Sample SMSAM Package. Consult the license
- which came with this software for your specific legal rights.
-
- */
-
-
-
- #ifndef __VIRTUALRAMORDISKFILE__
- #include "VirtualRamOrDiskFile.h"
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __RAMFILE__
- #include "RamFile.h"
- #endif
-
- #ifndef __ABSTRACTFILE__
- #include "AbstractFile.h"
- #endif
-
- #ifndef __STDIO__
- #include "StdIO.h"
- #endif
-
- #ifndef __THREADITULITIES__
- #include "ThreadUtilities.h"
- #endif
-
- #ifndef __DEBUGGINGGEAR__
- #include "DebuggingGear.h"
- #endif
-
- #ifndef __LIMITS__
- #include <Limits.h>
- #endif
-
- /***********************************|****************************************/
-
- #pragma segment VirtualFile
-
- DeclareList(TVirtualRamOrDiskFile,TVirtualRamOrDiskFileList);
- ImplementList(TVirtualRamOrDiskFile,TVirtualRamOrDiskFileList,false);
-
- /***********************************|****************************************/
-
- TVirtualRamOrDiskFileList gVirtualRamOrDiskFileList;
-
- /***********************************|****************************************/
-
- FSSpec TVirtualRamOrDiskFile::gDefaultStorageLocation;
-
- /***********************************|****************************************/
-
- extern ostream& DumpHex (ostream& s, const void *p, unsigned long size);
-
- /***********************************|****************************************/
-
- inline long min ( long a, long b )
- {
- return ( a < b) ? a : b;
- }
-
- /***********************************|****************************************/
-
- ostream& TVirtualRamOrDiskFile::operator >> ( ostream& s ) const
- {
- s << "TVirtualRamOrDiskFile @ " << ( void*) this;
- return s << ", " << TAbstractFile::operator >> ( s );
- }
-
- /***********************************|****************************************/
-
- TVirtualRamOrDiskFile::TVirtualRamOrDiskFile ( Location location ):
- TVirtualFile (),
- fFile ( nil ),
- fLocation ( location ),
- fRamLimit ( 64 * 1024 ),
- fLength ( 0 )
- {
- fFile = fLocation == kMemory ? new TRamFile : CreateDiskFile ();
- fFile->GetEnd ( fLength );
-
- gVirtualRamOrDiskFileList.Append ( this );
- }
-
- /***********************************|****************************************/
-
- TVirtualRamOrDiskFile::TVirtualRamOrDiskFile ( Location location, unsigned long ramToDiskThreshold ):
- TVirtualFile (),
- fFile ( nil ),
- fLocation ( location ),
- fRamLimit ( ramToDiskThreshold ),
- fLength ( 0 )
- {
- fFile = (fLocation == kMemory) ? new TRamFile : CreateDiskFile ();
- fFile->GetEnd ( fLength );
-
- gVirtualRamOrDiskFileList.Append ( this );
-
- }
-
- /***********************************|****************************************/
-
- TVirtualRamOrDiskFile::~TVirtualRamOrDiskFile()
- {
- gVirtualRamOrDiskFileList.Remove ( this );
-
- delete fFile;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::SetMaxMemSize ( unsigned long threshold )
- {
- fRamLimit = threshold;
- return ( fLocation == kMemory ) && ( fLength > fRamLimit ) ? ForceToDisk () : noErr;
- }
-
- /***********************************|****************************************/
-
- char* LocationStr ( const TVirtualRamOrDiskFile::Location& location )
- {
- if (location == TVirtualRamOrDiskFile::kMemory)
- return "inMemory";
- if (location == TVirtualRamOrDiskFile::kDisk)
- return "onDisk";
- return "location ???";
- }
-
- /***********************************|****************************************/
-
- unsigned long GetFilePosition(TAbstractFile* file )
- { long pos;
- OSErr err = file->GetPosition ( pos );
- if (err)
- pos = 0;
- return pos;
- }
-
- /***********************************|***************************************/
-
- unsigned long TVirtualRamOrDiskFile::GetVirtualRamOrDiskFilesCount ( )
-
- {
- return gVirtualRamOrDiskFileList.Count();
- }
-
- /**********************************|***************************************/
-
- unsigned long TVirtualRamOrDiskFile::GetVirtualRamOrDiskFilesSize ( )
- { unsigned long virtualRamOrDiskFilesSize = 0;
-
- unsigned long count = gVirtualRamOrDiskFileList.Count();
- for (unsigned int index = 1; index <= count; index++ )
- {
- TVirtualRamOrDiskFile* vF = gVirtualRamOrDiskFileList.Get ( index );
-
- long fileLength;
- if ( vF->GetEnd ( fileLength ) == noErr )
- virtualRamOrDiskFilesSize += fileLength;
- }
- return virtualRamOrDiskFilesSize;
- }
-
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::ReadData ( void* buffer, long& count )
- {
- #if debug
- if (steveFlag.Flag(18)) {
- keith << "TVRamOrDiskFile: Read(" << count << ") fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
- }
- #endif
-
- OSErr err = fFile ? fFile->ReadData ( buffer, count ) : fnOpnErr;
-
- #if debug
- if (steveFlag.Flag(18)) {
- keith << "TVRamOrDiskFile: Read, err=" << err << " DATA (" << count << ") fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
-
- DumpHex (keith, buffer, min ( count, 16 ) );
- }
- #endif
-
- return err;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::WriteData ( const void* buffer, long& count )
- {
- OSErr error;
-
- if ( fFile == nil )
- error = fnOpnErr;
- else if ( ( fLocation == kMemory ) && ( ( fLength + count ) > fRamLimit ) )
- error = ForceToDisk ();
- else
- error = noErr;
-
- #if debug
- if (steveFlag.Flag(18)) {
- keith << "TVRamOrDiskFile: Write(" << count << ") fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
- DumpHex (keith, buffer, min ( count, 16 ) );
- }
- #endif
-
- if ( !error )
- error = fFile->WriteData ( buffer, count );
-
- #if debug
- if (steveFlag.Flag(18)) {
- keith << "TVRamOrDiskFile:Write, done. err=" << error << " count=" << count << " fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
- }
- #endif
-
- fLength += count;
-
- return error;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::SetEnd ( long end )
- {
- OSErr error;
-
- if ( fFile == nil )
- error = fnOpnErr;
- else if ( ( fLocation == kMemory ) && ( end > fRamLimit ) )
- error = ForceToDisk ();
- else
- error = noErr;
-
- if ( !error )
- error = fFile->SetEnd ( end );
-
- if ( !error )
- fLength = end;
-
- return error;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::GetEnd ( long& end ) const
- {
- return fFile ? fFile->GetEnd ( end ) : fnOpnErr;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::SetPosition ( short mode, long offset )
- {
- return fFile ? fFile->SetPosition ( mode, offset ) : fnOpnErr;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::GetPosition ( long& position ) const
- {
- return fFile ? fFile->GetPosition ( position ) : fnOpnErr;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::ForceTo ( Location location, TAbstractFile* newFile )
- {
- OSErr error = noErr;
-
- if ( fFile )
- {
- FAILNULL ( newFile );
-
- error = newFile->SetEnd ( 0 );
-
- if ( !error )
- error = fFile->WriteTo ( *newFile );
-
- if ( !error )
- {
- delete fFile;
- fFile = newFile;
- fLocation = location;
- }
- else
- {
- delete newFile;
- }
- }
- else
- error = fnOpnErr;
-
- return error;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::ForceToDisk ()
- {
- keithF(18, "TVRamOrDiskFile:: ForceToDisk()" );
- return fLocation != kDisk ? ForceTo ( kDisk, CreateDiskFile () ) : noErr;
- }
-
- /***********************************|****************************************/
-
- OSErr TVirtualRamOrDiskFile::ForceToMemory ()
- {
- keithF(18, "TVRamOrDiskFile:: ForceToDisk()" );
- return fLocation != kMemory ? ForceTo ( kMemory, new TRamFile ) : noErr;
- }
-
- /***********************************|****************************************/
-
- void TVirtualRamOrDiskFile::UniqueFileName ( StringPtr name )
- {
- static unsigned long gUniqueFileID = 0;
- name [ 0 ] = sprintf ( (char*) &name [ 1 ], "TEMP-%li", ++gUniqueFileID );
- }
-
- /***********************************|****************************************/
-
- TAbstractFile*
- TVirtualRamOrDiskFile::CreateDiskFile ()
- {
- UniqueFileName ( gDefaultStorageLocation.name );
- return new TForkFile ( gDefaultStorageLocation );
- }
-
- /***********************************|****************************************/
- void TVirtualRamOrDiskFile::ForceFreeMemory (unsigned long neededFreeSpace )
- {
- Location location= kMemory ;
- unsigned long amountFreed = 0;
- unsigned long previousLastUsed = ULONG_MAX;
-
- unsigned long count = gVirtualRamOrDiskFileList.Count();
- for (unsigned int index = 1; index <= count; index++ )
- {
- while (amountFreed < neededFreeSpace)
- {
- TVirtualRamOrDiskFile* vF = gVirtualRamOrDiskFileList.Get ( index );
- if ( ( vF->GetLocation() == kMemory) && (vF->LastUsed() < previousLastUsed) )
- {
- previousLastUsed = vF->LastUsed();
- long fileLength;
- if ( vF->GetEnd ( fileLength ) == noErr ) {
- OSErr error = vF->ForceToDisk();
-
- amountFreed += fileLength;
- }
- }
- }
- }
- }
-